﻿//#include rfm

(function() {

if (!rfm.ui) {
    rfm.ui = {};
}

function rfm_ui_CellRenderer_ontransitionend_finalizeCell(e) {
    if (this.parentNode) {
        this.parentNode.removeChild(this);
    }
}

rfm.ui.CellRenderer = function(data, maxCellCount) {
    this.data = data;
    this.maxCellCount = maxCellCount;
    this.minPosition = -0.5;
    this.maxPosition = 1.5;
}
rfm.ui.CellRenderer.prototype = {
    allowFrontFill: true,
    allowBackFill: true,
    getCellData: function(cell) {
        return this.data[this.getCellIndex(cell)];
    },
    createCell: function(data, index) {
        var cell = document.createElement('div');
        this.setCellIndex(cell);
        return cell;
    },
    getCellIndex: function(cell) {
        return parseInt(cell.getAttribute('data-index'));
    },
    setCellIndex: function(cell, index) {
        cell.setAttribute('data-index', index);
    },
    clampCellIndex: function(index) {
        var dataCount = this.data.length;
        while (index > dataCount - 1) {
            index -= dataCount;
        }
        while (index < 0) {
            index += dataCount;
        }
        return index;
    },
    getCellPosition: function(cell) {
        return parseFloat(cell.getAttribute('data-position') || 1);
    },
    setCellPosition: function(cell, percent) {
        cell.setAttribute('data-position', percent);
    },
    getIncrement: function() {
        if (this.maxCellCount < 3) {
            return 1;
        }
        else if (this.maxCellCount == 3) {
            return 0.5;
        }
        else {
            return 1 / (this.maxCellCount - 3);
        }
    },
    shouldDropCell: function(cell) {
        var position = this.getCellPosition(cell);
        return position < this.minPosition || position > this.maxPosition;
    },
    dropCell: function(cell) {
        rfm_ui_CellRenderer_ontransitionend_finalizeCell.call(cell);
    },
    replenish: function(container) {
        var increment = this.getIncrement(),
            firstPerc,
            lastPerc,
            newIndex,
            newCell;
        while (this.allowFrontFill && (firstPerc = this.getCellPosition(container.firstChild)) > 0) {
            newIndex = this.clampCellIndex(this.getCellIndex(container.firstChild) - 1);
            newCell = this.createCell(this.data[newIndex], newIndex);
            this.setCellPosition(newCell, firstPerc - increment);
            container.insertBefore(newCell, container.firstChild);
        }
        while (this.allowBackFill && (lastPerc = this.getCellPosition(container.lastChild)) < 1) {
            newIndex = this.clampCellIndex(this.getCellIndex(container.lastChild) + 1);
            newCell = this.createCell(this.data[newIndex], newIndex);
            this.setCellPosition(newCell, lastPerc + increment);
            container.appendChild(newCell);
        }
    },
    redraw: function(container, offset, count, startIndex) {
        container.innerHTML = '';
        var numData = this.data.length,
            numCells = count || this.maxCellCount,
            increment = this.getIncrement(),
            cell,
            i = startIndex || 0,
            count = 0;
        offset = offset || 0;
        while (i < 0) {
            i += numData;
        }
        while (count < numCells) {
            cell = this.createCell(this.data[i], i);
            this.setCellPosition(cell, increment * count + offset);
            container.appendChild(cell);
            count++;
            if (++i >= numData) {
                i = 0;
            }
        }
    },
    rotate: function(container, delta, supportTransitions, suspendDelete) {
        var cell = container.firstChild,
            count = 0,
            position,
            nextCell;
        while (cell) {
            if (cell.nodeType == 1) {
                this.setCellPosition(cell, this.getCellPosition(cell) + delta);
                count++;
            }
            nextCell = cell.nextSibling;
            if (!suspendDelete && this.shouldDropCell(cell)) {
                if (supportTransitions) {
                    cell.$bind('webkitTransitionEnd', rfm_ui_CellRenderer_ontransitionend_finalizeCell, false);
                }
                else {
                    this.dropCell(cell);
                }
            }
            cell = nextCell;
        }
        this.replenish(container);
    },
    cleanup: function(container) {
        var cell = container.firstChild,
            next;
        while (cell) {
            next = cell.nextSibling;
            if (this.shouldDropCell(cell)) {
                this.dropCell(cell);
            }
            cell = next;
        }
        this.replenish(container);
    }
};

})();